package comp

import (
	"encoding/hex"
	"io"
	"log"
	"os"
	"strings"
)

const defaultHeaderLen = 20

// CFile _
type CFile struct {
	DeCompressDir string
	IgorePath     string
	Path          string            // 资源路径，可能是个目录，也可能是文件，或者是压缩文件
	DictPaths     map[string]string // 格式化好的资源路径数组，针对目录或者是压缩文件的格式化
	FileType      string            // 资源类型，是目录还是文件，还是压缩包
	Headers       []byte            // 存取的文件头信息，默认是长度是20字节
}

// Parse _
func (cf *CFile) Parse(path string, igorePath string) {
	cf.Path = path
	cf.IgorePath = igorePath

	fileInfo, err := os.Stat(path)
	if err != nil {
		log.Panicf("file stat error, err: %s", err.Error())
		return
	}

	if fileInfo.IsDir() {
		cf.FileType = TypeDir
	} else {
		file, err := os.Open(cf.Path)
		if err != nil {
			log.Panicf("os open error, err: %s", err.Error())
			return
		}
		defer file.Close()

		cf.Headers = cf.readHeader(file)
		headerStr := strings.ToUpper(hex.EncodeToString(cf.Headers))
		cf.FileType = checkFileType(headerStr)
	}

	cf.DictPaths = cf.GetSourcePaths()
}

// IsCompressed 该资源是不是压缩文件
func (cf *CFile) IsCompressed() bool {
	if cf.FileType == TypeUnknown || cf.FileType == TypeDir {
		return false
	}

	return true
}

func (cf *CFile) readHeader(file *os.File) []byte {
	buf := make([]byte, defaultHeaderLen)

	_, err := file.Read(buf)
	if err != nil && err != io.EOF {
		log.Println("read buf fail, err: ", err)
	}

	return buf
}

func checkFileType(headers string) string {
	for magic, t := range magicbytes {
		if strings.HasPrefix(headers, magic) {
			return t
		}
	}

	return TypeUnknown
}
